<template>
  <div id="index" ref="appRef">
    <div class="bg">
      <dv-loading v-if="loading">Loading...</dv-loading>
      <!-- 第一行 标题-->
      <div v-else class="host-body">
        <div class="d-flex jc-center">
          <div>
            <dv-decoration-10 class="dv-dec-10" />
            <div class="react-left">
                <span class="text" v-if="node">
                  {{node.name}}: {{node.ip}}
                </span>
            </div>
          </div>
          <div class="d-flex jc-center">
            <dv-decoration-8 class="dv-dec-8" :color="['#568aea', '#000000']" />
            <div class="title">
              <span class="title-text">{{ title }}</span>
              <dv-decoration-6
                class="dv-dec-6"
                :reverse="true"
                :color="['#50e3c2', '#67a1e5']"
              />
            </div>
            <dv-decoration-8
              class="dv-dec-8"
              :reverse="true"
              :color="['#568aea', '#000000']"
            />
          </div>
          <div>
            <dv-decoration-10 class="dv-dec-10" />
            <div class="react-right">
              <span class="text">
                {{ timeInfo.dateYear }}
                {{ timeInfo.dateDay }}
                {{ timeInfo.dateWeek }}
              </span>
              <div class="text">
                <a-button type="primary" size="small" @click="loginOut()" >
                  <template #icon><PoweroffOutlined /></template>
                  退出
                </a-button>
              </div>
            </div>
          </div>

        </div>
        <div class="body-box">
          <div class="content-box">
            <div>
              <dv-border-box-12>
                <!--  -->
                <dv-table :table="onlineUserTable" />
              </dv-border-box-12>
            </div>
            <div>
              <!-- 中间 -->
              <echarts-map-node-fly-lines :nodes="nodeList" :flows="flowList"/>
            </div>
            <div>
              <div>
                <dv-border-box-12>
                  <!-- -->
                  <echarts-bar-scroll  :chartBarRanking="flowRanking"/>
                </dv-border-box-12>
              </div>
              <div>
                <dv-border-box-12>
                  <!-- -->
                  <echarts-line-scroll :chartBarRanking="packetRanking"/>
                </dv-border-box-12>
              </div>

            </div>
          </div>
          <div class="bototm-box">
            <dv-border-box-12>
              <!-- -->
              <echarts-pie-dv-digital :numerical="userTotal"/>
            </dv-border-box-12>
            <dv-border-box-12>
              <!-- -->
              <echarts-bar-line-scroll :chartData="flowScroll"/>
            </dv-border-box-12>
            <dv-border-box-12>
              <!--  -->
              <dv-table-warn :table="warnTable"/>
            </dv-border-box-12>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  reactive,
  onMounted,
  onBeforeUnmount, toRefs,
} from 'vue'
import { useRouter } from 'vue-router';
import { PoweroffOutlined } from '@ant-design/icons-vue';
import { formatTime } from '@/utils'
import { title, subtitle, WEEK } from '@/constant'
import useDraw from '@/utils/useDraw'
import EchartsMapNodeFlyLines from '@/views/echarts/map/flylines/index.vue'
import DvTableWarn from '@/views/datav/table/warn/index.vue'

import DvTable from '@/views/datav/table/index.vue'
import EchartsPieDvDigital from '@/views/echartsdv/piedigital/index.vue'
import EchartsBarScroll from '@/views/echarts/bar/scroll/index.vue'
import EchartsLineScroll from '@/views/echarts/line/scroll/index.vue'
import EchartsBarLineScroll from '@/views/echarts/barline/scroll/index.vue'
import {api} from "@/axios/api";
import { StorageLocal,StorageSession } from "@/storage/storage";
export default defineComponent({
  components: {
    PoweroffOutlined,
    EchartsMapNodeFlyLines,
    EchartsBarLineScroll,
    EchartsPieDvDigital,
    DvTableWarn,
    EchartsBarScroll,
    EchartsLineScroll,
    DvTable,
  },
  setup() {
    const router = useRouter();
    // * 加载标识
    const loading = ref<boolean>(true)
    // * 时间内容
    const timeInfo = reactive({
      setInterval: 0,
      dateDay: '',
      dateYear: '',
      dateWeek: ''
    })
    // * 适配处理
    const { appRef, calcRate, windowDraw, unWindowDraw } = useDraw()

    // methods

    const loginOut = () => {
      // 删除选中的节点
      StorageSession.remove('node');
      // token
      StorageSession.remove('token');
      // 退出
      router.push({path:'/',"params":{}})
    }
    // todo 处理 loading 展示
    const cancelLoading = () => {
      setTimeout(() => {
        loading.value = false
      }, 500)
    }

    // todo 处理时间监听
    const handleTime = () => {
      timeInfo.setInterval = setInterval(() => {
        const date = new Date()
        timeInfo.dateDay = formatTime(date, 'HH: mm: ss')
        timeInfo.dateYear = formatTime(date, 'yyyy-MM-dd')
        timeInfo.dateWeek = WEEK[date.getDay()]
      }, 1000)
    }
    const nodeName ="XXX节点";
    /***********************************************/
    const timerInterval = reactive({
      interval: 0,
      times: 60000,
    })

    // 定义响应式数据 data
    const state= reactive({
      node :{name:"",ip: ""},
      nodeList: [],
      flowList: [[],[]],
      warnTable: {
        title: "全域状态信息",
        width: "350px",
        header: ['域名', '告警信息'],
        data:[],
      },
      flowRanking: {
        title: "全域流量信息",
        width: "350px",
        category:[],
        series:[{name:"发出流量",data:[]},{name:"接收流量",data:[]}],
      },packetRanking: {
        title: "全域数据包信息",
        width: "350px",
        category:[],
        series:[{name:"发出数据包数",data:[]},{name:"接收数据包数",data:[]}],
      },
      flowScroll: {
        title: "域节点流量信息",
        height: "230px",
        category:[],
        series:[{name:"带宽",data:[]},{name:"正常流量",data:[]},{name:"总流量",data:[]}],
        suffix: ['Kb', 'Mb']
      },
      onlineUserTable: {
        title: "在线用户",
        width: "350px",
        height: "770px",
        bgHeight: "740px",
        tbHeight: "700px",
        config: {
          header: ['NID', 'IP地址'],
          data: [],
          rowNum: 15, //表格行数
          headerHeight: 35,
          columnWidth: [50, 100],
          index: true,
          align: ['center']
        }
      },userTotal: {
        title: "在线率",
        digitals: [],
        pie:{
          width: "350px",
          height: "100px",
          xData: ['异常用户','离线用户','在线用户'],
          seriesColor: [ '#EB6841','#828c9d','#1370fb'],
          seriesData:[{ value: 0, name: '异常用户'},{value: 0, name: '离线用户' },{value: 0, name: '在线用户' }],
        }
      },


    });

    // 定义方法
    const methods = {
      async refreshNodeData(){
        await api.nodes.nodes().then((res: any) => {
          if (res && res.data && res.data.total > 0) {
            if (res.data.rows && res.data.rows.length >0) {
              state.nodeList=res.data.rows
              res.data.rows.forEach((node) => {
                if(node && node.ip){
                  StorageLocal.set("node-"+node.ip, node)
                }
              })
            }
          }
        })
      },
      async refreshNodesFlowData(){
        await api.nidtga.flyLines().then((res: any) => {
          if (res && res.data && res.data.code === 0) {
            if(res.data.normalFlow && res.data.normalFlow.length >0 ){
              state.flowList[0]= res.data.normalFlow
            }
            if(res.data.abnormalFlow && res.data.abnormalFlow.length >0 ){
              state.flowList[1]= res.data.abnormalFlow
            }
          }
        })
      },
      async refreshFlowData(){
        await api.nidtga.nodesFlow().then((res: any) => {
          if (res && res.data && res.data.code === 0) {
            if (res.data.data && res.data.data.length >0) {
              res.data.data.forEach((node,index) => {
                if(node && node.name){
                  // 流量
                  state.flowRanking.category[index] = node.name
                  // 发出流量
                  state.flowRanking.series[0].data[index]=Math.round(node.flowSend/1000)
                  // 接收流量
                  state.flowRanking.series[1].data[index]=Math.round(node.flowReceive/1000)
                  // 数据包
                  state.packetRanking.category[index] = node.name
                  // 发出数据包数
                  state.packetRanking.series[0].data[index]=node.packetSend
                  // 接收数据包数
                  state.packetRanking.series[1].data[index]=node.packetReceive

                  // 告警信息 状态：0-正常；1-流量异常; 2-数据包异常
                  let stateStr = "<span  class='colorGray'>未知状态</span>"
                  if( node.state === 0 ){
                    stateStr = "<span  class='colorGrass'>流量正常</span>"
                  }else if( node.state === 1 ){
                    stateStr = "<span  class='colorRed'>流量异常</span>"
                  }else if( node.state === 2 ){
                    stateStr = "<span  class='colorOrange'>数据包异常</span>"
                  }
                  state.warnTable.data[index] = [node.name, stateStr]

                }
              })
            }
          }
        })
      },
      async refreshChildFlowData(){
        await api.nidtga.nodeChildFlow().then((res: any) => {
          if (res && res.data && res.data.code === 0) {
            if (res.data.data && res.data.data.length >0) {
              res.data.data.forEach((node,index) => {
                if(node && node.name){
                  // 流量
                  state.flowScroll.category[index] = node.name
                  // 带宽
                  state.flowScroll.series[0].data[index]=node.bandwidth
                  // 异常流量
                  state.flowScroll.series[1].data[index]=Math.round(node.abnormalFlow/1000)
                  // 总流量（异常+正常）
                  state.flowScroll.series[2].data[index]=Math.round((node.abnormalFlow + node.normalFlow)/1000)
                }
              })
            }
          }
        })
      },
      async changeOnlineUser() {
        await api.nidtga.online().then((res: any) => {
          if (res && res.data && res.data.total > 0) {
            if (res.data.rows && res.data.rows.length > 0) {
              console.log("mock Online User :" + res.data.rows.length)
               res.data.rows.forEach((user,index) => {
                if(user){
                  let ipStr = '';
                  if(user.address){
                    if(user.address.indexOf(":")>0){
                      // IPv6
                      ipStr = "<span  class='colorGrass' title='"+user.address+"'>"+user.address+"</span>";
                    }else if(user.address.indexOf(".")>0){
                      // IPv4
                      ipStr = "<span  class='colorBlue' title='"+user.address+"'>"+user.address+"</span>";
                    }else{
                      ipStr = "<span  class='colorText' title='"+user.address+"'>"+user.address+"</span>";
                    }
                  }
                  state.onlineUserTable.config.data[index] = [user.nid,ipStr]
                }
              })
            }
          }
        })
      }, async changeUserTotal() {
        await api.nidtga.usersCount().then((res: any) => {
          if (res && res.data && res.data.code === 0) {
              //console.log("mock User total:" + res.data.total)

              let pieData = reactive({
                newList:[]
              })
            let onlineNumber = 0
            if(res.data.online) {
              onlineNumber = res.data.online
            }
            let offlineNumber = 0
            if(res.data.offline) {
              offlineNumber = res.data.offline
            }

            let abnormalNumber = 0
            if(res.data.abnormal) {
              abnormalNumber = res.data.abnormal
            }

            const totalNumber = onlineNumber + offlineNumber + abnormalNumber;
            const online = {
                text: '在线用户数量',
                icon: 'icon-diagnose',
                config: {
                  number: [ onlineNumber],
                  toFixed: 0,// 小数点位数
                  content: '{nt}',
                  style: {
                    fontSize: 24,
                    fill: '#1370fb' //
                  }
                }
              }


              const abnormal = {
                text: '异常用户数量',
                icon: 'icon-early-warning',
                config: {
                  number: [ abnormalNumber],
                  toFixed: 0,// 小数点位数
                  content: '{nt}',
                  style: {
                    fontSize: 24,
                    fill: '#EB6841' //
                  }
                }
              }
              const offline = {
                text: '离线用户数量',
                icon: 'icon-clouddownload',
                config: {
                  number: [ offlineNumber],
                  toFixed: 0,// 小数点位数
                  content: '{nt}',
                  style: {
                    fontSize: 24,
                    fill: '#828c9d' //
                  }
                }
              }

            const total = {
              text: '总用户数量',
              icon: 'icon-tongji2',
              config: {
                number: [ totalNumber],
                toFixed: 0,// 小数点位数
                content: '{nt}',
                style: {
                  fontSize: 24,
                  fill: '#3de7c9' //
                }
              }
            }
              state.userTotal.digitals[0] = online
              state.userTotal.digitals[1] = total
              state.userTotal.digitals[2] = abnormal
              state.userTotal.digitals[3] = offline

              state.userTotal.pie.seriesData[0].value = abnormalNumber
              state.userTotal.pie.seriesData[1].value = offlineNumber
              state.userTotal.pie.seriesData[2].value = onlineNumber
          }
        })
      },
      async changeNodesAllFlow() {
        await api.nidtga.nodesAllFlow().then((res: any) => {
          if (res && res.data && res.data.code === 0) {
            if (res.data.data && res.data.data.length > 0) {
              //console.log("mock nodes flow packet :" + res.data.data.length)
              res.data.data.forEach((node,index) => {
                if(node){
                  state.flowScroll.series[0].data[index]=node.bandwidth
                  state.flowScroll.category[index] = node.nodeName
                  // send流量
                  state.flowScroll.series[1].data[index]=node.send
                  // all流量
                  state.flowScroll.series[2].data[index]=node.receive
                }
              })
            }
          }
        })
      },
      async initData() {
        let node = StorageSession.get('node')
        if(!node){
          state.node=node
        }
        await methods.refreshNodeData()
        await methods.refreshNodesFlowData()
        await methods.refreshFlowData()
        await methods.refreshChildFlowData()
        await methods.changeOnlineUser()

        await methods.changeUserTotal()
        await methods.changeNodesAllFlow()
        setTimeout(function(){
          if(state.nodeList.length<=0){
             methods.refreshNodeData()
          }
        },2000);
      },
      async changeTiming() {
        timerInterval.interval = setInterval(() => {
          methods.refreshNodeData()
          methods.refreshNodesFlowData()
          methods.refreshFlowData()
          methods.refreshChildFlowData()
          methods.changeOnlineUser()

          methods.changeUserTotal()
          methods.changeNodesAllFlow()
        }, timerInterval.times)
      },
    }


    // 生命周期
    onMounted(() => {
      cancelLoading()
      handleTime()
      // todo 屏幕适应
      windowDraw()
      calcRate()
      methods.initData()
      methods.changeTiming()
    })

    onBeforeUnmount(() => {
      unWindowDraw()
      clearInterval(timeInfo.setInterval)
    })

    // return
    return {
      loading,
      timeInfo,
      appRef,
      title,
      subtitle,
      nodeName,
      ...toRefs(state),
      loginOut,
      ...methods,
    }
  }
})
</script>

<style lang="scss" scoped>
@import '@/assets/scss/index.scss';
</style>
